home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / bin / geteltorito < prev    next >
Text File  |  2009-10-02  |  6KB  |  215 lines

  1. #!/usr/bin/perl
  2.  
  3. use Getopt::Std;
  4.  
  5. #
  6. # geteltorito.pl: a bootimage extractor
  7. # Script that will extract the first El Torito bootimage from a
  8. # bootable CD image
  9. # R. Krienke 08/2001
  10. # krienke@uni-koblenz.de
  11. # License: GPL
  12. #
  13. # Get latest version from:
  14. # http://www.uni-koblenz.de/~krienke/ftp/noarch/geteltorito
  15. #
  16. $utilVersion="0.4"; 
  17. #
  18. # Version 0.4
  19. #    2007/02/01
  20. #    A patch from Santiago Garcia <manty@debian.org> to use a virtual sector
  21. #    size (vSecSize) of 512 bytes, as defined on "El Torito" specs and change
  22. #    unpack of the sector count from n to v to get the correct sector count.
  23. # Version 0.3
  24. #    2006/02/21
  25. #    A patch from  Ben Collins <bcollins@ubuntu.com> to make the 
  26. #    utility work on PPC machines (change from 'L'-encoding in pack to 'V')
  27. # Version 0.2
  28. #    Several patches included from Nathan Stratton Treadway(nathant@ontko.com)
  29. #    to adjust the platform output as well as fixes for other minor bugs
  30. # Version 0.1
  31. #    Initial release
  32. #
  33. # For information on El Torito see 
  34. # http://wikipedia.org/
  35. # or try this link directly:
  36. # http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/Platform+System+Software+Documents/default.htm
  37.  
  38. $vSecSize=512;
  39. $secSize=2048;
  40. $ret=undef;$version=undef;$opt_h=undef;$loadSegment=undef;$systemType=undef;
  41.  
  42. #
  43. # Read a particular sector from a file
  44. # sector counting starts at 0, not 1
  45. #
  46. sub getSector{
  47.    my ($secNum, $secCount, $file)=@_;
  48.    my ($sec, $count);
  49.  
  50.    open(FILE, $file) || die "Cannot open \"$file\" \n";
  51.  
  52.    seek(FILE, $secNum*$secSize, 0);
  53.    $count=read(FILE, $sec, $vSecSize*$secCount, 0) ;
  54.    if( $count != $vSecSize*$secCount ){
  55.        warn "Error reading from file \"$file\"\n";
  56.    }
  57.    close(FILE);
  58.  
  59.    return($sec);
  60. }
  61.  
  62.  
  63. #
  64. # Write eltorito data into a file
  65. #
  66. sub writeOutputFile{
  67.    my($name)=shift;
  68.    my($value)=shift;
  69.  
  70.    open(OUT, ">".$name)|| die "$0: Cannot open outputfile \"$name\" for writing. Stop.";
  71.    print OUT $value;
  72.    close(OUT);
  73. }
  74.  
  75.  
  76. #
  77. # Usage
  78. #
  79. sub usage{
  80.     warn "\n$0 [-hv] [-o outputfilename] cd-image \n",
  81.         "Script will try to extract an El Torito image from a \n",
  82.         "bootable CD (or cd-image) given by <cd-image> and write \n",
  83.         "the data extracted to STDOUT or to a file.\n",
  84.         "   -h:        This help. \n",
  85.         "   -v:        Print version of script and exit.\n",
  86.         "   -o <file>: Write extracted data to file <file> instead of STDOUT.\n",
  87.         "\n\n";
  88.     exit 0;    
  89. }
  90.  
  91.  
  92. # ---------------------------------------------------------------------
  93. $ret=getopts('hvo:');
  94.  
  95. if( defined($opt_v) ){
  96.      warn "Version: $utilVersion \n";
  97.     exit 0;
  98. }
  99.  
  100. if( defined($opt_h) || $#ARGV <0 ){
  101.          usage(0);
  102. }     
  103.  
  104. if( defined($opt_o) ){
  105.    $outputFilename="$opt_o";
  106. }
  107.      
  108. $imageFile=$ARGV[0];
  109.  
  110. if( ! -r $imageFile ){
  111.     die "Cannot read image/device \"$imageFile\". Aborting\n";
  112. }
  113.  
  114. #
  115. # Read Sector 17 from CD which should contain a Boot Record Volume
  116. # descriptor. This descriptor contains at its start the text ($isoIdent)
  117. # CD001     and ($toritoSpec)
  118. # EL TORITO SPECIFICATION
  119. # see http://www.cdpage.com/Compact_Disc_Variations/eltoritoi.html
  120. # for details
  121. #
  122.  
  123. $sector=getSector(17, 1, $imageFile );
  124. ($boot, $isoIdent, $version, $toritoSpec,
  125.      $unUsed, $bootP)= unpack( "Ca5CA32A32V", $sector );
  126.  
  127. if( $isoIdent ne "CD001" || $toritoSpec ne "EL TORITO SPECIFICATION" ){
  128.     die "This data image does not seem to be a bootable CD-image\n";
  129. }    
  130.  
  131. #
  132. # Now fetch the sector of the booting catalog 
  133. #
  134. $sector=getSector($bootP, 1, $imageFile );
  135.  
  136. print STDERR "Booting catalog starts at sector: $bootP \n";
  137.  
  138. # The first 32 bytes of this sector contains the validation entry for a
  139. # boot. The first byte has to be 01, the next byte determines the
  140. # architecture the image is designed for, where 00 is i86, 01 is PowerPC
  141. # and 02 is Mac. More data give info about manufacturer, etc.  The 
  142. # final two bytes must contain 0x55 and 0xAA respectively (as 
  143. # defined by the El Torito standard).
  144.  
  145. $validateEntry=substr($sector, 0, 32);
  146.  
  147. ($header, $platform, $unUsed, $manufact, $unUsed, $five, $aa)=
  148.                unpack( "CCvA24vCC", $validateEntry);
  149.  
  150. if( $header != 1 || $five != 0x55 || $aa != 0xaa ){
  151.     die "Invalid Validation Entry on image \n";
  152. }
  153.  
  154. print STDERR "Manufacturer of CD: $manufact\n";
  155. print STDERR "Image architecture: ";
  156. print STDERR "x86" if( $platform == 0 );
  157. print STDERR "PowerPC" if( $platform == 1 );
  158. print STDERR "Mac" if( $platform == 2 );
  159. print STDERR "unknown ($platform)" if( $platform > 2 );
  160. print STDERR "\n";
  161.  
  162. #
  163. # Now we examine the initial/defaultentry which follows the validate
  164. # entry and has a size of 32 bytes. 
  165.  
  166. $initialEntry=substr($sector, 32, 32);
  167.  
  168. ($boot, $media, $loadSegment, $systemType, $unUsed, 
  169.        $sCount, $imgStart, $unUsed)=unpack( "CCvCCvVC", $initialEntry);
  170.  
  171. if( $boot != 0x88 ){
  172.     die "Boot indicator in Initial/Default-Entry is not 0x88. CD is not bootable. \n";
  173. }    
  174.  
  175. print STDERR "Boot media type is: ";
  176. if( $media == 0 ){
  177.     print STDERR "no emulation";
  178.     $count=0;
  179. }
  180. if( $media == 1 ){
  181.     print STDERR "1.2meg floppy";
  182.        $count=1200*1024/$vSecSize;  
  183. }
  184. if( $media == 2 ){
  185.     print STDERR "1.44meg floppy";
  186.        $count=1440*1024/$vSecSize;  
  187. }
  188. if( $media == 3 ){
  189.     print STDERR "2.88meg floppy";
  190.        $count=2880*1024/$vSecSize;  
  191. }
  192. if( $media == 4 ){
  193.     print STDERR "harddisk";
  194.     $count=0;
  195. }
  196. print STDERR "\n";
  197.  
  198. # Only use the internal sector counter if the real size is unknown
  199. # ($count==0)
  200. $cnt=$count==0?$sCount:$count;
  201.  
  202. print STDERR "El Torito image starts at sector $imgStart and has $cnt sector(s) of $vSecSize Bytes\n";
  203.  
  204. # We are there:
  205. # Now read the bootimage to stdout
  206. $image=getSector($imgStart, $cnt, $imageFile);
  207.  
  208. if( length($outputFilename) ){
  209.    writeOutputFile($outputFilename, $image);
  210.    print STDERR "\nImage has been written to file \"$outputFilename\".\n";
  211. }else{
  212.    print "$image";
  213.    print STDERR "Image has been written to stdout ....\n"; 
  214. }
  215.